<template>
	<view class="content">
		<view class="bgColor">
			<image src="/static/examine/msgBg.png" mode=""></image>
		</view>
		<cusHeaderVue :titleContent="pageTitle" :showBack="true" colorText="#333333"></cusHeaderVue>

		<scroll-view scroll-y="true" class="form-scroll-view" :style="{paddingTop: `calc(${scrollerHeight} + 90rpx)`}">
			<view class="form-container" v-if="formFields.length > 0">
				<!-- 请假时的提示展示 -->
				<view v-if="isLeaveForm && leaveDurationText" class="leave-tip">{{ leaveDurationText }}</view>
				<!-- 动态表单组件 -->
				<view class="form-item" v-for="(field, index) in visibleFormFields" :key="index">
					<view class="form-label">
						{{ field.title }}
						<text class="required" v-if="field.$required">*</text>
					</view>
					<view class="form-value">
						<!-- 选择器组件 -->
						<view v-if="field.type === 'select'" class="select-wrapper">
							<picker :range="field.options" :range-key="'label'"
								@change="handleSelectChange($event, field)" class="custom-picker">
								<view class="picker-display">
									{{ getSelectedLabel(field.field) || field.placeholder || '请选择' }}
								</view>
							</picker>
							<!-- 物料选择后显示库存与已领取数量 -->
							<view v-if="field.field === 'materials' && materialsInfo && materialsInfo.stock !== null"
								class="materials-extra">
								库存：{{ materialsInfo.stock }}，已领取：{{ materialsInfo.ylSum }}
							</view>
						</view>

						<!-- 输入框组件 -->
						<input v-else-if="field.type === 'input'" :value="formData[field.field] || ''"
							@input="handleInputChange($event, field)"
							:placeholder="field.placeholder || field.info || ''"
							:disabled="field.props?.disabled || field.props?.readonly" class="custom-input"
							:class="{ 'readonly-input': field.props?.disabled || field.props?.readonly }" />

						<!-- 数字输入框组件 -->
						<input v-else-if="field.type === 'inputNumber'" type="number"
							:value="formData[field.field] ?? ''" @input="handleNumberChange($event, field)"
							:placeholder="field.placeholder || field.info || '请输入'"
							:disabled="field.props?.disabled || field.props?.readonly" class="custom-input"
							:class="{ 'readonly-input': field.props?.disabled || field.props?.readonly }" />

						<!-- 多行文本输入框组件 -->
						<textarea v-else-if="field.type === 'textarea'" :value="formData[field.field] || ''"
							@input="handleInputChange($event, field)"
							:placeholder="field.placeholder || field.info || ''" class="custom-textarea"
							:auto-height="true" />

						<!-- 单选框组件 -->
						<view v-else-if="field.type === 'radio'" class="radio-group">
							<view v-for="option in field.options" :key="option.value" class="radio-item"
								@click="handleRadioChange(option.value, field)">
								<view class="radio-circle"
									:class="{ 'radio-checked': formData[field.field] === option.value }">
									<view class="radio-inner" v-if="formData[field.field] === option.value"></view>
								</view>
								<view class="radio-label">{{ option.label }}</view>
							</view>
						</view>

						<!-- 多选框组件 -->
						<view v-else-if="field.type === 'checkbox'" class="checkbox-group">
							<view v-for="option in field.options" :key="option.value" class="checkbox-item"
								@click="handleCheckboxChange(option.value, field)">
								<view class="checkbox-square"
									:class="{ 'checkbox-checked': getCheckboxStatus(field.field, option.value) }">
									<view class="checkbox-icon" v-if="getCheckboxStatus(field.field, option.value)">✓
									</view>
								</view>
								<view class="checkbox-label">{{ option.label }}</view>
							</view>
						</view>

						<!-- 上传图片组件 -->
						<view
							v-if="(field.type === 'upload' && field.props?.accept === 'image') || field.type === 'UploadImgs'"
							class="upload-group">
							<view class="upload-item" v-for="(img, imgIndex) in getUploadImages(field.field)"
								:key="imgIndex">
								<image :src="img" mode="aspectFill"
									@error="handleImageError($event, field.field, imgIndex)" class="upload-image">
								</image>
								<view class="upload-delete" @click.stop="handleDeleteImage(field.field, imgIndex)">×
								</view>
							</view>
							<button class="upload-btn" @click="handleUploadImage(field.field)">上传图片</button>
						</view>


						<!-- 日期/时间选择器组件 -->
						<view v-else-if="field.type === 'datePicker'" class="date-time-picker-wrapper">

							<picker mode="date" :value="formData[field.field + '_date'] || ''"
								@change="handleDatePickerChange($event, field, 'date')" class="custom-picker">
								<view class="picker-display">
									日期：{{ formData[field.field + '_date'] || '请选择日期' }}
								</view>
							</picker>

							<view class="period-selector" v-if="isLeaveForm">
								<view class="period-item" :class="{ 'active': getPeriod(field) === 'AM' }"
									@click="handlePeriodSelect('AM', field)">上午</view>
								<view class="period-item" :class="{ 'active': getPeriod(field) === 'PM' }"
									@click="handlePeriodSelect('PM', field)">下午</view>
							</view>

							<!-- 	<picker
								v-if="isLeaveForm"
								mode="time"
								:value="formData[field.field + '_time'] || ''"
								@change="handleDatePickerChange($event, field, 'time')"
								class="custom-picker"
							>
								<view class="picker-display">
									时间：{{ formData[field.field + '_time'] || '请选择时间' }}
								</view>
							</picker> -->
							<view v-if="!isLeaveForm" class="period-selector">
								<view class="period-item" :class="{ 'active': getPeriod(field) === 'AM' }"
									@click="handlePeriodSelect('AM', field)">上午</view>
								<view class="period-item" :class="{ 'active': getPeriod(field) === 'PM' }"
									@click="handlePeriodSelect('PM', field)">下午</view>
							</view>
							<picker v-if="!isLeaveForm" mode="time" :value="formData[field.field + '_time'] || ''"
								@change="handleDatePickerChange($event, field, 'time')" class="custom-picker">
								<view class="picker-display">
									时间：{{ formData[field.field + '_time'] || '请选择时间' }}
								</view>
							</picker>
						</view>

						<!-- 文件上传组件 -->
						<view v-else-if="field.type === 'upload' && field.props?.accept === 'file'"
							class="file-upload-group">
							<view class="file-item" v-for="(file, fileIndex) in getUploadFiles(field.field)"
								:key="fileIndex">
								<view class="file-icon">📄</view>
								<view class="file-name">{{ file.name }}</view>
								<view class="file-delete" @click.stop="handleDeleteFile(field.field, fileIndex)">×
								</view>
							</view>
							<button class="file-upload-btn" @click="handleUploadFile(field.field)">上传文件</button>
						</view>
					</view>
					<!-- <view class="form-info" v-if="field.title">{{ field.title }}</view> -->
				</view>
				<view style="height: 400rpx;width: 100%;"></view>
				<!-- 提交按钮 -->
				<view class="submit-container">
					<button class="submit-btn" @click="submitForm" :loading="submitting">
						{{ submitting ? '提交中...' : '提交申请' }}
					</button>
				</view>
			</view>

			<!-- 加载状态 -->
			<view class="loading-container" v-else-if="loading">
				<view class="loading-spinner"></view>
				<text class="loading-text">加载中...</text>
			</view>

			<!-- 错误状态 -->
			<view class="error-container" v-else-if="error">
				<text class="error-text">{{ error }}</text>
				<button class="retry-btn" @click="loadProcessDefinition">重试</button>
			</view>
		</scroll-view>
	</view>
</template>

<script setup>
	import {
		onLoad,
	} from '@dcloudio/uni-app';
	import {
		ref,
		computed,
		onMounted,
		nextTick,
		watch
	} from 'vue';
	import cusHeaderVue from '@/components/cus-header.vue';
	const loadingGuardTimer = ref(null);
	// 离线模式（不调用任何数据接口也能渲染）
	import {
		GETProcessDefinitionGet,
		POSTProcessInstanceCreate,
		uploadImage,
		GETMaterialsBaseInfo,
		GETMaterialsAllList
	} from '@/api/interface.js';
	// 离线模式（不调用任何数据接口也能渲染）
	let OFFLINE_MODE = false;

	// 响应式数据
	const scrollerHeight = ref('');
	const loading = ref(false);
	const error = ref('');
	const processDefinition = ref(null);
	const formFields = ref([]);
	const formData = ref({});
	const submitting = ref(false);
	const processId = ref('');
	const materialsInfo = ref(null);
	const pageTitle = ref('物料领取申请'); // 默认标题




	// 离线模式（不调用任何数据接口也能渲染）
	const buildDefaultFormFields = () => ([{
			field: 'materials',
			title: '选择物料',
			type: 'select',
			options: [],
			placeholder: '请选择',
			on: {
				change: ['materialsName']
			}
		},
		{
			field: 'materialsName',
			title: '物料名称',
			type: 'input',
			props: {
				readonly: true
			}
		},
		{
			field: 'slNum',
			title: '申请数量',
			type: 'inputNumber',
			placeholder: '请输入数量',
			$required: true
		},
		{
			field: 'reasonStr',
			title: '申请事由',
			type: 'textarea',
			placeholder: '请输入申请事由',
			$required: true
		},
	]);

	// 离线：注入示例物料选项（包含库存与已领取）
	const loadMaterialsListOffline = () => {
		const materialsField = formFields.value.find(f => f.field === 'materials');
		if (materialsField) {
			materialsField.options = [{
					label: '示例物料A',
					value: 'demo-1',
					stock: 120,
					ylSum: 6
				},
				{
					label: '示例物料B',
					value: 'demo-2',
					stock: 45,
					ylSum: 0
				},
			];
		}
	};

	// 页面加载
	onLoad((options) => {
		getBarHeight();
		if (options && options.title) {
			pageTitle.value = decodeURIComponent(options.title);
		}
		if (OFFLINE_MODE) {
			// 不调用任何后端接口，使用本地表单+示例物料
			formFields.value = buildDefaultFormFields();
			loadMaterialsListOffline();
			loading.value = false;
			return;
		}
		// 在线模式：调用流程定义接口
		if (options && options.id) {
			processId.value = options.id;
			loadProcessDefinition(options.id);
		} else {
			loadProcessDefinition('_wzslsp:17:833b7ef3-9d0f-11f0-ae24-2a133986788e');
		}
	});


	// 获取状态栏高度
	const getBarHeight = () => {
		uni.getSystemInfo({
			success: function(res) {
				scrollerHeight.value = res.statusBarHeight + 'px'
			}
		});
	}

	// 解析表单字段
	const parseFormFields = (fields) => {
		try {
			const parsedFields = fields.map(fieldStr => {
				const field = JSON.parse(fieldStr);
				// 初始化表单数据
				if (field.$required && field.type === 'radio' && field.options && field.options.length > 0) {
					formData.value[field.field] = field.options[0].value;
				}
				return field;
			});
			return parsedFields;
		} catch (err) {
			console.error('解析表单字段失败:', err);
			return [];
		}
	}

	// 兜底：从 bpmnXml 提取 fieldsPermission 并构建基本表单字段
	const buildFormFieldsFromBpmnXml = (xml) => {
		if (!xml || typeof xml !== 'string') return [];
		const result = [];
		try {
			// 提取 <flowable:fieldsPermission field="..." title="..." .../> 行
			const regex = /<flowable:fieldsPermission\s+[^>]*field="([^"]+)"\s+[^>]*title="([^"]+)"[^>]*>/g;
			let m;
			const pairs = [];
			while ((m = regex.exec(xml)) !== null) {
				pairs.push({
					field: m[1],
					title: m[2]
				});
			}
			// 根据已知字段映射类型
			for (const p of pairs) {
				if (p.field === 'materials') {
					result.push({
						field: 'materials',
						title: p.title || '选择物料',
						type: 'select',
						options: [],
						placeholder: '请选择',
						on: {
							change: ['materialsName']
						}
					});
				} else if (p.field === 'materialsName') {
					// 此字段由选择联动产生，不直接展示
					result.push({
						field: 'materialsName',
						title: p.title || '物料名称',
						type: 'input',
						props: {
							readonly: true
						}
					});
				} else if (p.field === 'slNum') {
					result.push({
						field: 'slNum',
						title: p.title || '申请数量',
						type: 'inputNumber',
						placeholder: '请输入数量',
						$required: true
					});
				} else if (p.field === 'reasonStr') {
					result.push({
						field: 'reasonStr',
						title: p.title || '申请事由',
						type: 'textarea',
						placeholder: '请输入申请事由',
						$required: true
					});
				} else {
					// 其他未知字段，默认使用输入框
					result.push({
						field: p.field,
						title: p.title || p.field,
						type: 'input',
						placeholder: '请输入'
					});
				}
			}
			console.log('根据bpmnXml构建的字段：', result);
			return result;
		} catch (e) {
			console.error('bpmnXml解析失败：', e);
			return [];
		}
	};

	// 过滤掉不展示的字段
	const visibleFormFields = computed(() => {
		const hiddenTitles = ['物料名称', '当前库存', '已领取'];
		return (Array.isArray(formFields.value) ? formFields.value : []).filter(f => {
			const t = String(f?.title || '').trim();
			return !hiddenTitles.includes(t);
		});
	});


	// 预先拉取物料列表，写入 materials 字段 options（兼容不同字段名）
	const loadMaterialsList = async () => {
		try {
			const res = await GETMaterialsAllList({});
			console.log('物料列表响应:', res);
			const list = res?.data?.list;
			if (res && res.code === 0 && Array.isArray(list)) {
				const options = list.map(item => ({
					label: item.label ?? item.name ?? item.materialsName ?? item.title ?? '未命名物料',
					value: item.value ?? item.id ?? item.materialsId ?? item.code ?? String(Math
						.random()),
					stock: item.stock ?? item.quantity ?? item.currentStock ?? null,
					ylSum: item.ylSum ?? item.receiveNum ?? item.received ?? null
				}));
				const materialsField = formFields.value.find(f => f.field === 'materials');
				if (materialsField) {
					materialsField.options = options;
				}
			} else {
				console.warn('物料列表为空或结构不匹配');
			}
		} catch (err) {
			console.error('获取物料列表失败:', err);
		}
	};

	// 获取选中的标签
	const getSelectedLabel = (fieldName) => {
		const field = formFields.value.find(f => f.field === fieldName);
		if (!field || !field.options) return '';
		const option = field.options.find(opt => opt.value === formData.value[fieldName]);
		return option ? option.label : '';
	};

	// 处理选择器变化（支持联动 materialsName + 库存/已领取兜底请求）
	const handleSelectChange = async (e, field) => {
		try {
			if (!field || !Array.isArray(field.options)) return;
			const idx = e && e.detail && typeof e.detail.value !== 'undefined' ? Number(e.detail.value) : -1;
			if (idx < 0 || idx >= field.options.length) return;
			const opt = field.options[idx];
			// 写入选中的值
			formData.value[field.field] = opt.value;

			// 若配置有联动字段，优先填充 materialsName
			if (field.field === 'materials') {
				const nameVal = opt.label ?? opt.name ?? opt.materialsName ?? opt.title ?? '';
				if (nameVal && formFields.value.some(f => f.field === 'materialsName')) {
					formData.value['materialsName'] = nameVal;
				}
				// 先用列表内的库存/已领取
				const stockVal = opt.stock ?? null;
				const ylVal = opt.ylSum ?? null;
				materialsInfo.value = {
					stock: stockVal,
					ylSum: ylVal
				};

				// 在线模式下，如果缺少库存/已领取，则回退调用基础信息接口
				if (!OFFLINE_MODE && (stockVal == null || ylVal == null)) {
					console.log('列表缺少库存/已领取，回退查询基础信息', opt);
					try {
						const baseRes = await GETMaterialsBaseInfo({
							id: opt.id ?? opt.value
						});
						console.log('基础信息响应:', baseRes);
						if (baseRes && baseRes.code === 0 && baseRes.data) {
							const d = baseRes.data;
							const s = d.stock ?? d.quantity ?? d.currentStock ?? d.kc ?? 0;
							const y = d.ylSum ?? d.receiveNum ?? d.received ?? d.ylNum ?? 0;
							materialsInfo.value = {
								stock: s,
								ylSum: y
							};
						}
					} catch (err) {
						console.warn('获取物料基础信息失败:', err);
					}
				}
			}
		} catch (err) {
			console.warn('选择器处理失败:', err);
		}
	};

	// 处理输入框变化
	const handleInputChange = (e, field) => {
		formData.value[field.field] = e.detail.value;
	};

	// 处理数字输入框变化
	const handleNumberChange = (e, field) => {
		const value = e.detail.value;
		if (value === '' || /^\d*\.?\d*$/.test(value)) {
			formData.value[field.field] = value === '' ? '' : Number(value);
		}
	};

	// 处理单选框变化
	const handleRadioChange = (value, field) => {
		formData.value[field.field] = value;
	};

	// 处理多选框变化
	const handleCheckboxChange = (value, field) => {
		if (!Array.isArray(formData.value[field.field])) {
			formData.value[field.field] = [];
		}
		const index = formData.value[field.field].indexOf(value);
		if (index > -1) {
			formData.value[field.field].splice(index, 1);
		} else {
			formData.value[field.field].push(value);
		}
	};

	// 获取多选框状态
	const getCheckboxStatus = (fieldName, value) => {
		return Array.isArray(formData.value[fieldName]) && formData.value[fieldName].includes(value);
	};

	// 获取上传的图片
	const getUploadImages = (fieldName) => {
		console.log(formData.value[fieldName])
		console.log(formData.value[fieldName])
		return Array.isArray(formData.value[fieldName]) ? formData.value[fieldName] : [];
	};

	// 获取上传的文件
	const getUploadFiles = (fieldName) => {
		return Array.isArray(formData.value[fieldName]) ? formData.value[fieldName] : [];
	};

	// 处理图片上传
	const handleUploadImage = async (fieldName) => {
		uni.chooseImage({
			count: 9,
			success: async (res) => {
				// 显示加载提示
				uni.showLoading({
					title: '上传中...'
				});

				try {
					// 确保表单字段存在
					if (!formData.value[fieldName]) {
						formData.value[fieldName] = [];
					}

					// 逐个上传图片
					for (const tempFilePath of res.tempFilePaths) {
						// 调用上传接口
						const uploadRes = await uploadImage(tempFilePath, 'requisition');
						console.log('Upload response:', uploadRes);

						// 处理返回的URL - 优先使用 uploadRes.url
						let imageUrl = '';
						if (uploadRes && uploadRes.url) {
							imageUrl = String(uploadRes.url);
						} else if (uploadRes.data && typeof uploadRes.data === 'object' && uploadRes
							.data.url) {
							// 兼容旧格式
							imageUrl = String(uploadRes.data.url);
						} else if (typeof uploadRes.data === 'string') {
							// 兼容可能的直接字符串格式
							imageUrl = uploadRes.data;
						}

						// 优化URL提取逻辑
						if (typeof imageUrl === 'string') {
							imageUrl = imageUrl.replace(/[`]/g, '').trim();
						}

						// 最终验证和修复
						if (!imageUrl || !imageUrl.startsWith('http')) {
							console.warn('URL验证失败，尝试从完整响应中提取:', imageUrl);
							const fullResponseStr = JSON.stringify(uploadRes);
							const backupRegex = /(https?:\/\/[^\s`"'\)]+)/g;
							const matches = fullResponseStr.match(backupRegex);
							if (matches && matches.length > 0) {
								imageUrl = matches[0];
							} else {
								imageUrl =
									'https://via.placeholder.com/100x100/cccccc/666666?text=Image';
							}
						}

						// 最终清理确保没有反引号残留
						if (typeof imageUrl === 'string') {
							imageUrl = imageUrl.replace(/[`]/g, '');
						}

						// 强制重新创建数组以确保响应式更新
						formData.value[fieldName] = [...formData.value[fieldName], imageUrl];
					}

					// 使用nextTick确保DOM更新
					await nextTick();

					uni.showToast({
						title: '上传成功',
						icon: 'success'
					});
				} catch (error) {
					console.error('图片上传失败:', error);
					uni.showToast({
						title: '上传失败，请重试',
						icon: 'none'
					});
				} finally {
					// 隐藏加载提示
					uni.hideLoading();
				}
			}
		});
	};

	// 处理图片删除
	const handleDeleteImage = (fieldName, index) => {
		formData.value[fieldName].splice(index, 1);
	};

	// 处理图片加载错误
	const handleImageError = (event, fieldName, imgIndex) => {
		// 避免Vue prop warning by handling the event properly
		if (event && event.preventDefault) {
			event.preventDefault();
		}

		console.error('图片加载错误:', event);
		console.log('字段名:', fieldName, '图片索引:', imgIndex);

		// 安全检查确保字段和索引存在
		if (!formData.value[fieldName] || !Array.isArray(formData.value[fieldName]) || imgIndex >= formData.value[
				fieldName].length) {
			console.error('无效的字段名或索引');
			return;
		}

		// 获取出错的URL
		let errorUrl = formData.value[fieldName][imgIndex];
		console.log('导致错误的图片URL:', errorUrl);

		// 修复：检查URL是否被反引号包裹，如果是，尝试清理
		if (typeof errorUrl === 'string' && (errorUrl.startsWith('`') || errorUrl.includes('`'))) {
			const cleanUrl = errorUrl.replace(/[`]/g, '');
			console.log('清理反引号后的URL:', cleanUrl);

			// 如果清理后的URL是有效的网络图片，使用它而不是替换为占位图
			if (cleanUrl.startsWith('http')) {
				try {
					const updatedImages = [...formData.value[fieldName]];
					updatedImages[imgIndex] = cleanUrl;
					formData.value[fieldName] = updatedImages;
					console.log('已修复被反引号包裹的URL:', cleanUrl);
					return; // 修复成功，不继续替换
				} catch (err) {
					console.error('更新清理后的URL失败:', err);
				}
			}
		}

		// 只在URL不是有效的网络图片时使用在线占位图
		if (typeof errorUrl === 'string' && !errorUrl.startsWith('http')) {
			const onlinePlaceholderUrl = 'https://via.placeholder.com/100x100/cccccc/666666?text=Image';

			// 安全地更新数组
			try {
				const updatedImages = [...formData.value[fieldName]];
				updatedImages[imgIndex] = onlinePlaceholderUrl;
				formData.value[fieldName] = updatedImages;
				console.log('已替换为在线占位图片:', onlinePlaceholderUrl);
			} catch (err) {
				console.error('更新图片数据失败:', err);
			}
		} else {
			console.log('URL已是有效的网络图片，不进行替换');
		}
	};

	// 处理文件上传
	const handleUploadFile = (fieldName) => {
		uni.chooseMessageFile({
			count: 1,
			type: 'file',
			success: (res) => {
				if (!formData.value[fieldName]) {
					formData.value[fieldName] = [];
				}
				formData.value[fieldName].push(...res.tempFiles);
			}
		});
	};

	// 处理文件删除
	const handleDeleteFile = (fieldName, index) => {
		formData.value[fieldName].splice(index, 1);
	};

	// 日期时间选择器处理函数
	const handleDatePickerChange = (e, field, type) => {
		console.log(`${type} picker change handler called with field:`, field.field);

		// 确保正确获取选择的值
		let selectedValue;
		if (e && e.detail && e.detail.value !== undefined) {
			selectedValue = e.detail.value;
		} else {
			console.warn('Invalid event data:', e);
			return;
		}

		console.log('Selected value:', selectedValue);

		// 分别保存日期和时间部分
		const fieldSuffix = type === 'date' ? '_date' : '_time';
		const targetField = field.field + fieldSuffix;

		// 确保formData是响应式更新的 - formData是ref对象，始终通过value访问
		formData.value[targetField] = selectedValue;
		console.log(`Form data updated for ${targetField}:`, formData.value[targetField]);

		// 获取当前存储的值
		const dateValue = formData.value[field.field + '_date'];
		const timeValue = formData.value[field.field + '_time'];

		// 如果日期和时间都已选择，则拼接完整值
		if (dateValue && timeValue) {
			const combinedValue = dateValue + ' ' + timeValue;
			formData.value[field.field] = combinedValue;
			console.log('Combined datetime value:', combinedValue);
		}
	};

	// 表单验证
	const validateForm = () => {
		for (const field of formFields.value) {
			if (field.$required) {
				const value = formData.value[field.field];
				if (value === undefined || value === null || value === '') {
					uni.showToast({
						title: `${field.title}不能为空`,
						icon: 'none'
					});
					return false;
				}
				if (Array.isArray(value) && value.length === 0) {
					uni.showToast({
						title: `${field.title}至少选择一项`,
						icon: 'none'
					});
					return false;
				}
			}
		}
		return true;
	};

	// 提交表单
	const submitForm = async () => {
		if (!validateForm()) {
			return;
		}

		submitting.value = true;
		try {
			// 准备提交数据
			const submitData = {
				processDefinitionId: processId.value || '_wzslsp:17:833b7ef3-9d0f-11f0-ae24-2a133986788e',
				variables: {
					...formData.value
				}
			};

			const res = await POSTProcessInstanceCreate(submitData);
			if (res.code === 0) {
				uni.showToast({
					title: '提交成功',
					icon: 'success'
				});
				// 延时返回上一页
				setTimeout(() => {
					uni.navigateBack();
				}, 1500);
			} else {
				uni.showToast({
					title: res.message || '提交失败',
					icon: 'none'
				});
			}
		} catch (err) {
			console.error('提交表单失败:', err);
			uni.showToast({
				title: '网络错误，请重试',
				icon: 'none'
			});
		} finally {
			submitting.value = false;
		}
	};

	// 根据ID获取流程定义详情
	const loadProcessDefinition = async (id) => {
		if (loadingGuardTimer.value) {
			clearTimeout(loadingGuardTimer.value);
			loadingGuardTimer.value = null;
		}
		loading.value = true;
		error.value = '';
		// 安全兜底：若长时间未返回，自动结束加载并提示
		loadingGuardTimer.value = setTimeout(() => {
			if (loading.value) {
				console.warn('加载流程定义超时，结束加载');
				loading.value = false;
				error.value = '加载超时，请稍后重试';
			}
		}, 12000);
		try {
			const res = await GETProcessDefinitionGet({
				id
			});
			console.log('流程定义详情响应:', res);
			if (res.code === 0 && res.data) {
				processDefinition.value = res.data;
				// 优先解析后端返回的 formFields
				if (res.data.formFields && Array.isArray(res.data.formFields) && res.data.formFields.length > 0) {
					formFields.value = parseFormFields(res.data.formFields);
					applyQjTimeReadonly?.();
					await loadMaterialsList();
				} else {
					// 兜底：从 bpmnXml 生成基本字段
					const fromXml = buildFormFieldsFromBpmnXml(res.data.bpmnXml);
					formFields.value = fromXml;
					applyQjTimeReadonly?.();
					await loadMaterialsList();
					if (!fromXml || fromXml.length === 0) {
						console.warn('formFields缺失，且bpmnXml未解析到字段，页面可能不渲染表单');
					}
				}
			} else {
				error.value = '获取流程定义失败';
			}
		} catch (err) {
			console.error('获取流程定义详情失败:', err);
			error.value = '网络错误，请重试';
		} finally {
			loading.value = false;
			if (loadingGuardTimer.value) {
				clearTimeout(loadingGuardTimer.value);
				loadingGuardTimer.value = null;
			}
		}
	}

	// 请假 AM/PM 逻辑
	const isLeaveForm = computed(() => {
		const title = pageTitle.value || '';
		if (title.includes('请假')) return true;
		// 兼容：如果表单包含 qjTime 字段或至少两个日期选择器，也视为请假表单
		const hasQjTime = formFields.value.some(f => f.field === 'qjTime');
		const datePickerCount = formFields.value.filter(f => f.type === 'datePicker').length;
		return hasQjTime || datePickerCount >= 2;
	});

	// 辅助：定位开始/结束时间字段
	const getLeaveStartField = () => formFields.value.find(f => f.type === 'datePicker' && ((f.title && f.title.includes(
		'开始')) || (f.field && /start|begin/i.test(f.field))));
	const getLeaveEndField = () => formFields.value.find(f => f.type === 'datePicker' && ((f.title && (f.title.includes(
		'结束') || f.title.includes('截止'))) || (f.field && /end|finish/i.test(f.field))));

	const handlePeriodSelect = (period, field) => {
		// 上午/下午映射规则：
		// 开始-AM -> 08:30:00；开始-PM -> 12:00:00
		// 结束-AM -> 12:00:00；结束-PM -> 17:30:00
		const startField = getLeaveStartField();
		const endField = getLeaveEndField();
		let timeStr = '';
		if (startField && field.field === startField.field) {
			timeStr = period === 'AM' ? '08:30:00' : '12:00:00';
		} else if (endField && field.field === endField.field) {
			timeStr = period === 'AM' ? '12:00:00' : '17:30:00';
		} else {
			// 回退：若无法识别字段类型，采用通用范围
			timeStr = period === 'AM' ? '08:30:00' : '17:30:00';
		}

		formData.value[field.field + '_period'] = period;
		formData.value[field.field + '_time'] = timeStr;
		const dateValue = formData.value[field.field + '_date'];
		if (dateValue) {
			formData.value[field.field] = dateValue + ' ' + timeStr;
		}
	};

	const getPeriod = (field) => {
		return formData.value[field.field + '_period'] || '';
	};

	const leaveDurationText = computed(() => {
		if (!isLeaveForm.value) return '';
		const startField = formFields.value.find(f => f.type === 'datePicker' && ((f.title && f.title.includes(
			'开始')) || (f.field && /start|begin/i.test(f.field))));
		const endField = formFields.value.find(f => f.type === 'datePicker' && ((f.title && (f.title.includes(
			'结束') || f.title.includes('截止'))) || (f.field && /end|finish/i.test(f.field))));
		if (!startField || !endField) return '';
		const sDate = formData.value[startField.field + '_date'];
		const sPeriod = formData.value[startField.field + '_period'];
		const eDate = formData.value[endField.field + '_date'];
		const ePeriod = formData.value[endField.field + '_period'];
		if (!sDate || !eDate || !sPeriod || !ePeriod) return '';
		if (sDate === eDate) {
			if (sPeriod === 'AM' && ePeriod === 'AM') return '请假半天';
			if (sPeriod === 'AM' && ePeriod === 'PM') return '请假一天';
			if (sPeriod === 'PM' && ePeriod === 'PM') return '请假半天';
			if (sPeriod === 'PM' && ePeriod === 'AM') return '时间选择有误';
		} else {
			const s = new Date(sDate);
			const e = new Date(eDate);
			if (isNaN(s.getTime()) || isNaN(e.getTime())) return '';
			const diffDays = Math.floor((e - s) / (24 * 3600 * 1000)) + 1; // 跨天包含首尾两天
			let total = diffDays;
			if (sPeriod === 'PM') total -= 0.5; // 下午开始，首日算半天
			if (ePeriod === 'AM') total -= 0.5; // 上午结束，末日算半天
			if (total <= 0) return '时间选择有误';
			return `请假${total}天`;
		}
		return '';
	});

	// 计算数值时长（天）并写入 qjTime
	const leaveDaysNumber = computed(() => {
		if (!isLeaveForm.value) return null;
		const startField = formFields.value.find(f => f.type === 'datePicker' && ((f.title && f.title.includes(
			'开始')) || (f.field && /start|begin/i.test(f.field))));
		const endField = formFields.value.find(f => f.type === 'datePicker' && ((f.title && (f.title.includes(
			'结束') || f.title.includes('截止'))) || (f.field && /end|finish/i.test(f.field))));
		if (!startField || !endField) return null;
		const sDate = formData.value[startField.field + '_date'];
		const sPeriod = formData.value[startField.field + '_period'];
		const eDate = formData.value[endField.field + '_date'];
		const ePeriod = formData.value[endField.field + '_period'];
		if (!sDate || !eDate || !sPeriod || !ePeriod) return null;
		if (sDate === eDate) {
			if (sPeriod === 'AM' && ePeriod === 'AM') return 0.5;
			if (sPeriod === 'AM' && ePeriod === 'PM') return 1;
			if (sPeriod === 'PM' && ePeriod === 'PM') return 0.5;
			if (sPeriod === 'PM' && ePeriod === 'AM') return null;
		} else {
			const s = new Date(sDate);
			const e = new Date(eDate);
			if (isNaN(s.getTime()) || isNaN(e.getTime())) return null;
			const diffDays = Math.floor((e - s) / (24 * 3600 * 1000)) + 1;
			let total = diffDays;
			if (sPeriod === 'PM') total -= 0.5;
			if (ePeriod === 'AM') total -= 0.5;
			if (total <= 0) return null;
			return total;
		}
		return null;
	});

	watch([leaveDaysNumber, isLeaveForm], ([days, leave]) => {
		if (!leave) return;
		if (days != null) {
			formData.value.qjTime = days;
		}
	});

	// 使 qjTime 字段只读禁用（请假表单）
	const applyQjTimeReadonly = () => {
		if (!isLeaveForm.value) return;
		const qjField = formFields.value.find(f => f.field === 'qjTime');
		if (qjField) {
			qjField.props = qjField.props || {};
			qjField.props.disabled = true;
			qjField.props.readonly = true;
			if (!qjField.placeholder) qjField.placeholder = '系统自动计算';
		}
	};
</script>

<style lang="scss" scoped>
	.content {
		width: 100%;
		height: 100vh;
		position: relative;
		overflow: hidden;
	}

	.bgColor {
		width: 100%;
		height: 740rpx;
		position: absolute;
		z-index: -1;
		top: 0;

		image {
			width: 100%;
			height: 100%;
		}
	}

	.form-scroll-view {
		height: 100vh;
		overflow-y: auto;
	}

	.form-container {
		padding: 30rpx;
		padding-bottom: 100rpx;
	}

	.form-item {
		background: #ffffff;
		border-radius: 16rpx;
		padding: 30rpx;
		margin-bottom: 30rpx;
		box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
	}

	.form-label {
		font-size: 28rpx;
		font-weight: 500;
		color: #333333;
		margin-bottom: 20rpx;
		display: flex;
		align-items: center;
	}

	.required {
		color: #ff4d4f;
		margin-left: 8rpx;
	}

	.form-value {
		margin-bottom: 10rpx;
	}

	.form-info {
		font-size: 24rpx;
		color: #999999;
		line-height: 36rpx;
	}

	// 选择器样式
	.select-wrapper {
		width: 100%;
	}

	.custom-picker {
		width: 100%;
		cursor: pointer;
		user-select: none;
		z-index: 10;
	}

	.picker-display {
		padding: 24rpx 0;
		font-size: 28rpx;
		color: #666666;
		border-bottom: 1rpx solid #f0f0f0;
		position: relative;
		padding-right: 40rpx;
		width: 100%;
		height: 80rpx;
		display: flex;
		align-items: center;
		box-sizing: border-box;
		z-index: 5;
		background: white;

		&::after {
			content: '>';
			position: absolute;
			right: 0;
			top: 50%;
			transform: translateY(-50%) rotate(90deg);
			font-size: 24rpx;
			color: #999;
		}

		&:active {
			background-color: rgba(254, 175, 56, 0.1);
		}
	}

	// 新增：物料信息展示样式
	.materials-extra {
		margin-top: 12rpx;
		font-size: 24rpx;
		color: #666;
	}

	.custom-input {
		width: 100%;
		padding: 24rpx 0;
		font-size: 28rpx;
		color: #333;
		border-bottom: 1rpx solid #f0f0f0;
	}

	.readonly-input {
		color: #999;
		background: #fafafa;
	}

	// 多行文本输入框样式
	.custom-textarea {
		width: 100%;
		min-height: 150rpx;
		font-size: 28rpx;
		color: #333;
		line-height: 42rpx;
		padding: 20rpx 0;
		border-bottom: 1rpx solid #f0f0f0;
	}

	// 单选框样式
	.radio-group {
		display: flex;
		flex-wrap: wrap;
		margin: -10rpx;
	}

	.radio-item {
		display: flex;
		align-items: center;
		margin: 10rpx;
		padding: 10rpx 0;
	}

	.radio-circle {
		width: 32rpx;
		height: 32rpx;
		border: 2rpx solid #d9d9d9;
		border-radius: 50%;
		margin-right: 10rpx;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.radio-checked {
		border-color: #feaf38;
	}

	.radio-inner {
		width: 16rpx;
		height: 16rpx;
		border-radius: 50%;
		background: #feaf38;
	}

	.radio-label {
		font-size: 28rpx;
		color: #333;
	}

	// 多选框样式
	.checkbox-group {
		display: flex;
		flex-wrap: wrap;
		margin: -10rpx;
	}

	.checkbox-item {
		display: flex;
		align-items: center;
		margin: 10rpx;
		padding: 10rpx 0;
	}

	.checkbox-square {
		width: 32rpx;
		height: 32rpx;
		border: 2rpx solid #d9d9d9;
		border-radius: 6rpx;
		margin-right: 10rpx;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.checkbox-checked {
		background: #feaf38;
		border-color: #feaf38;
	}

	.checkbox-icon {
		color: white;
		font-size: 20rpx;
		font-weight: bold;
	}

	.checkbox-label {
		font-size: 28rpx;
		color: #333;
	}

	// 图片上传样式
	.upload-group {
		display: flex;
		flex-wrap: wrap;
		margin: -10rpx;
		padding: 10rpx 0; // 增加内边距避免内容紧贴边框
	}

	.upload-item {
		width: 200rpx;
		height: 200rpx;
		margin: 10rpx;
		position: relative;
		overflow: hidden; // 确保图片不会超出容器
		border-radius: 8rpx; // 添加圆角保持一致性
		background-color: #f5f5f5; // 添加背景色，在图片加载前显示
	}

	.upload-image {
		width: 100%;
		height: 100%;
		border-radius: 8rpx;
		object-fit: cover; // 保持图片比例并填充容器
		display: block; // 移除图片底部间隙
	}

	.upload-delete {
		position: absolute;
		top: -10rpx;
		right: -10rpx;
		width: 40rpx;
		height: 40rpx;
		background: rgba(0, 0, 0, 0.6);
		color: white;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 32rpx;
		font-size: 24rpx; // 调整删除按钮大小
		z-index: 10; // 确保在图片上方显示
	}

	.upload-btn {
		width: 200rpx;
		height: 200rpx;
		margin: 10rpx;
		border: 2rpx dashed #d9d9d9;
		border-radius: 8rpx;
		background-color: #f5f5f5;
		color: #666;
		font-size: 24rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-direction: column;

		&::after {
			border: none; // 移除默认按钮边框
		}
	}


	.upload-add {
		width: 200rpx;
		height: 200rpx;
		margin: 10rpx;
		border: 2rpx dashed #d9d9d9;
		border-radius: 8rpx;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.upload-icon {
		width: 60rpx;
		height: 60rpx;
		margin-bottom: 10rpx;
	}

	.upload-text {
		font-size: 24rpx;
		color: #999;
	}

	// 文件上传样式
	.file-upload-group {
		width: 100%;
	}

	.file-item {
		display: flex;
		align-items: center;
		padding: 20rpx;
		background: #f5f5f5;
		border-radius: 8rpx;
		margin-bottom: 20rpx;
		position: relative;
	}

	.file-icon {
		font-size: 40rpx;
		margin-right: 20rpx;
	}

	.file-name {
		flex: 1;
		font-size: 26rpx;
		color: #333;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.file-delete {
		position: absolute;
		right: 20rpx;
		font-size: 32rpx;
		color: #999;
	}

	.file-upload-btn {
		width: 100%;
		padding: 24rpx;
		background: #f5f5f5;
		color: #666;
		font-size: 28rpx;
		border: none;
		border-radius: 8rpx;
	}

	// 提交按钮样式
	.submit-container {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		padding: 20rpx 30rpx;
		background: #ffffff;
		box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
		z-index: 999;
		box-sizing: border-box;
	}

	// 滚动视图样式调整
	.form-scroll-view {
		padding-bottom: 200rpx;
		/* 增加底部内边距，确保图片上传区域不被遮挡 */
	}

	// 日期时间选择器样式
	.date-time-picker-wrapper {
		width: 100%;
		margin-bottom: 10rpx;
	}

	.date-picker-section,
	.time-picker-section {
		width: 100%;
		margin-bottom: 10rpx;
		padding: 10rpx 0;
	}

	// 上午/下午时间段选择器样式
	.period-selector {
		display: flex;
		gap: 16rpx;
		margin-bottom: 16rpx;
	}

	.period-item {
		flex: 1;
		text-align: center;
		padding: 18rpx 0;
		border: 1rpx solid #f0f0f0;
		border-radius: 10rpx;
		font-size: 28rpx;
		color: #666;
		background: #fff;
	}

	.period-item.active {
		border-color: #feaf38;
		background: rgba(254, 175, 56, 0.12);
		color: #f98434;
	}

	// 请假提示样式
	.leave-tip {
		margin: 10rpx 0 20rpx;
		padding: 16rpx 20rpx;
		background: rgba(254, 175, 56, 0.08);
		border: 1rpx solid rgba(254, 175, 56, 0.35);
		border-radius: 10rpx;
		color: #f98434;
		font-size: 26rpx;
	}

	.submit-btn {
		width: 100%;
		height: 96rpx;
		background: linear-gradient(-90deg, #feaf38, #f98434);
		color: white;
		font-size: 32rpx;
		font-weight: 500;
		border: none;
		border-radius: 48rpx;
		box-shadow: 0 4rpx 16rpx rgba(249, 132, 52, 0.3);
	}

	// 加载样式
	.loading-container {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		height: 60vh;
	}

	.loading-spinner {
		width: 60rpx;
		height: 60rpx;
		border: 6rpx solid #f3f3f3;
		border-top: 6rpx solid #feaf38;
		border-radius: 50%;
		animation: spin 1s linear infinite;
		margin-bottom: 20rpx;
	}

	@keyframes spin {
		0% {
			transform: rotate(0deg);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	.loading-text {
		font-size: 28rpx;
		color: #999;
	}

	// 错误样式
	.error-container {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		height: 60vh;
		padding: 40rpx;
	}

	.error-text {
		font-size: 28rpx;
		color: #ff4d4f;
		margin-bottom: 30rpx;
		text-align: center;
	}

	.retry-btn {
		padding: 20rpx 60rpx;
		background: #feaf38;
		color: white;
		border: none;
		border-radius: 40rpx;
		font-size: 28rpx;
	}
</style>